package com.shop.cereshop.business.service.order.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.business.dao.order.CereShopOrderDAO;
import com.shop.cereshop.business.page.finance.*;
import com.shop.cereshop.business.page.order.Product;
import com.shop.cereshop.business.page.order.ShopOrder;
import com.shop.cereshop.business.param.finance.FinanceCountParam;
import com.shop.cereshop.business.param.finance.FinanceDetailParam;
import com.shop.cereshop.business.param.finance.FinanceWithdrawalParam;
import com.shop.cereshop.business.param.order.OrderGetAllParam;
import com.shop.cereshop.business.service.order.CereShopOrderService;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.domain.after.CereOrderDilever;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.order.CereShopOrder;
import com.shop.cereshop.commons.domain.product.CereProductSku;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class CereShopOrderServiceImpl implements CereShopOrderService {

    @Autowired
    private CereShopOrderDAO cereShopOrderDAO;

    @Override
    public Page getAll(OrderGetAllParam param) throws CoBusinessException {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<ShopOrder> list = cereShopOrderDAO.getAll(param);
        //过滤空对象
        list.stream().filter(Objects::nonNull);
        //w给订单赋值商品名称
        for (ShopOrder a : list) {
            List<Product> products = cereShopOrderDAO.getProducts(a.getOrderId());
            if (!EmptyUtils.isEmpty(products)) {
                //封装规格属性数据
                products.forEach(product -> product.setSkuDetails(cereShopOrderDAO.findSkuAttribute(product.getOrderProductId())));
            }
//            List<String> names = cereShopOrderDAO.getNames(a.getOrderId());
            //w给订单赋值商品名称
            String s = "";
            for (int i = 0; i < products.size(); i++) {
                if (i == products.size() - 1) {
                    s += products.get(i).getProductName();
                } else {
                    s += products.get(i).getProductName() + ",";
                }

            }
            a.setProNames(s);
            //w这个classifyId只是用来区分商品和积分商品的
            List<Long> longList = cereShopOrderDAO.getClassifyId(a.getOrderId());
            if (longList.size() > 0) {
                Long classifyId = longList.get(0);
                a.setClassifyId(classifyId);
                if (classifyId == 7) {
                    a.setPrice(a.getPrice().multiply(new BigDecimal(10)));
                }
            }
        }
        PageInfo<ShopOrder> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public ShopOrder getById(Long orderId) throws CoBusinessException {
        ShopOrder shopOrder = cereShopOrderDAO.getById(orderId);
        if (shopOrder != null) {
            //根据买家账户查询下单总数
            shopOrder.setTotal(cereShopOrderDAO.getOrderTotals(shopOrder.getBuyerUserId()));
            //查询商品信息
            List<Product> products = cereShopOrderDAO.getProducts(orderId);
            if (!EmptyUtils.isEmpty(products)) {
                //封装规格属性数据
                products.forEach(product -> product.setSkuDetails(cereShopOrderDAO.findSkuAttribute(product.getOrderProductId())));
            }
            shopOrder.setProducts(products);
        }
        CereOrderDilever dilever = cereShopOrderDAO.getDilever(orderId);
        if (dilever != null) {
            shopOrder.setOrderDilever(dilever);
            shopOrder.setLogisticsCompanyName(cereShopOrderDAO.getLogisticsCompanyName(dilever.getExpress()));
        }
        return shopOrder;
    }

    @Override
    public void updateState(CereShopOrder cereShopOrder) throws CoBusinessException {
        cereShopOrderDAO.updateState(cereShopOrder);
    }

    @Override
    public FinanceCount getFinanceCount(FinanceCountParam param) throws CoBusinessException {
        FinanceCount count = new FinanceCount();
        //查询累计营业额
        //w排除积分
        count.setTurnover(cereShopOrderDAO.getTurnover(param.getShopId()));
        //查询冻结金额
        //w排除积分
        count.setFrozenMoney(cereShopOrderDAO.getFrozenMoney(param.getShopId()));
        //查询提现中金额
        count.setWithdrawableStayMoney(cereShopOrderDAO.getWithdrawableStayMoney(param.getShopId()));
        //查询总的可提现金额
        //w排除积分
        BigDecimal withdrawableMoney = cereShopOrderDAO.getAllWithdrawableMoney(param.getShopId());
        //查询已提现的金额
        BigDecimal money = cereShopOrderDAO.getWithdrawableMoney(param.getShopId());
        //计算可提现金额=总的提现金额-提现中金额-已提现金额
        count.setWithdrawableMoney(withdrawableMoney.subtract(count.getWithdrawableStayMoney()).subtract(money));
        if (IntegerEnum.DAY_CONDITION.getCode().equals(param.getCondition())) {
            //查询指定月份下每天的收入
            List<Finance> incomes = cereShopOrderDAO.getFinanceByDay(param.getShopId(), param.getTime(), 1);
            //查询指定月份下每天的支出
            List<Finance> expenditures = cereShopOrderDAO.getFinanceByDay(param.getShopId(), param.getTime(), 2);
            //将支出数据转为map
            Map<String, Finance> map = expenditures.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toMap(Finance::getTime, Function.identity()));
            if (!EmptyUtils.isEmpty(incomes)) {
                incomes.forEach(a -> {
                    if (!EmptyUtils.isEmpty(map.get(a.getTime()))) {
                        a.setExpenditure(map.get(a.getTime()).getIncome());
                    }
                });
            }
            count.setFinances(incomes);
        } else {
            //查询指定月份下每月的收入
            List<Finance> incomes = cereShopOrderDAO.getFinanceByMonth(param.getShopId(), param.getTime(), 1);
            //查询指定月份下每月的支出
            List<Finance> expenditures = cereShopOrderDAO.getFinanceByMonth(param.getShopId(), param.getTime(), 2);
            //将支出数据转为map
            Map<String, Finance> map = expenditures.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toMap(Finance::getTime, Function.identity()));
            if (!EmptyUtils.isEmpty(incomes)) {
                incomes.forEach(a -> {
                    if (!EmptyUtils.isEmpty(map.get(a.getTime()))) {
                        a.setExpenditure(map.get(a.getTime()).getIncome());
                    }
                });
            }
            count.setFinances(incomes);
        }
        return count;
    }

    @Override
    public Bank getBank(Long shopId) throws CoBusinessException {
//        //查询提现中金额
//        BigDecimal stayMoney = cereShopOrderDAO.getWithdrawableStayMoney(shopId);
//        //查询总的可提现金额
//        BigDecimal withdrawableMoney = cereShopOrderDAO.getAllWithdrawableMoney(shopId);
//        //查询已提现的金额
//        BigDecimal money=cereShopOrderDAO.getWithdrawableMoney(shopId);
//        //计算可提现金额=总的提现金额-提现中金额-已提现金额
//        BigDecimal total = withdrawableMoney.subtract(stayMoney).subtract(money);
//        if(total.compareTo(new BigDecimal(0))!=1){
//            throw new CoBusinessException(CoReturnFormat.BALANCE_NOT_ENOUGH);
//        }
        return cereShopOrderDAO.getBank(shopId);
    }

    @Override
    public List<WithdrawalDetail> getWithdrawalDetails(FinanceWithdrawalParam param) throws CoBusinessException {
        return cereShopOrderDAO.getWithdrawalDetails(param);
    }

    @Override
    public Page getDetails(FinanceDetailParam param) throws CoBusinessException {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        //查询当天所有流水数据
        List<FlowingWater> list = cereShopOrderDAO.getDetails(param);
        if (!EmptyUtils.isEmpty(list)) {
            list.forEach(a -> {
                a.setShopId(param.getShopId());
                //查询流水发生时的冻结金额和可用余额之和
                a.setBalance(getBalance(a));
            });
        }
        PageInfo<FlowingWater> pageInfo = new PageInfo<>(list);
        Page page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public void updateBatchStock(List<CereProductSku> skus) throws CoBusinessException {
        cereShopOrderDAO.updateBatchStock(skus);
    }

    @Override
    public BigDecimal getWithdrawableStayMoney(Long shopId) {
        return cereShopOrderDAO.getWithdrawableStayMoney(shopId);
    }

    @Override
    public BigDecimal getAllWithdrawableMoney(Long shopId) {
        return cereShopOrderDAO.getAllWithdrawableMoney(shopId);
    }

    @Override
    public BigDecimal getWithdrawableMoney(Long shopId) {
        return cereShopOrderDAO.getWithdrawableMoney(shopId);
    }

    @Override
    public CereShopOrder findById(Long orderId) {
        return cereShopOrderDAO.selectByPrimaryKey(orderId);
    }

    @Override
    public List<Long> getOrderId() {
        return cereShopOrderDAO.getOrderId();
    }

    @Override
    public void updateState2(List<Long> ids) {
        cereShopOrderDAO.updateState2(ids);
    }

    private BigDecimal getBalance(FlowingWater flowingWater) {
        BigDecimal decimal = new BigDecimal(0);
        //根据该流水发生时间查询截止到这个时间为止的冻结金额
        BigDecimal frozen = cereShopOrderDAO.getTurnoverByTime(flowingWater);
        //根据该流水发生时间查询截止到这个时间为止的提现中金额
        BigDecimal decimal1 = cereShopOrderDAO.getWithdrawableStayMoneyByTime(flowingWater);
        //根据该流水发生时间查询截止到这个时间为止的总可提现金额
        BigDecimal decimal2 = cereShopOrderDAO.getAllWithdrawableMoneyByTime(flowingWater);
        //根据该流水发生时间查询截止到这个时间为止的已提现金额
        BigDecimal decimal3 = cereShopOrderDAO.getWithdrawableMoneyByTime(flowingWater);
        //计算可提现金额=总的提现金额-提现中金额-已提现金额
        BigDecimal decimal4 = decimal2.subtract(decimal1).subtract(decimal3);
        return decimal.add(frozen).add(decimal4);
    }
}
